package org.cybzacg.encryption.monitoring.metrics;

import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Map;

/**
 * 加密指标类
 * 收集和统计加密操作的各种指标数据
 * 
 * @author encryption team
 * @version 1.0
 */
public class EncryptionMetrics {
    
    // 加密操作统计
    private final AtomicLong totalEncryptions = new AtomicLong(0);
    private final AtomicLong successfulEncryptions = new AtomicLong(0);
    private final AtomicLong failedEncryptions = new AtomicLong(0);
    
    // 解密操作统计
    private final AtomicLong totalDecryptions = new AtomicLong(0);
    private final AtomicLong successfulDecryptions = new AtomicLong(0);
    private final AtomicLong failedDecryptions = new AtomicLong(0);
    
    // 签名操作统计
    private final AtomicLong totalSignatures = new AtomicLong(0);
    private final AtomicLong successfulSignatures = new AtomicLong(0);
    private final AtomicLong failedSignatures = new AtomicLong(0);
    
    // 验证操作统计
    private final AtomicLong totalVerifications = new AtomicLong(0);
    private final AtomicLong successfulVerifications = new AtomicLong(0);
    private final AtomicLong failedVerifications = new AtomicLong(0);
    
    // 按算法分类的统计
    private final Map<String, AlgorithmMetrics> algorithmMetrics = new ConcurrentHashMap<>();
    
    // 时间统计
    private volatile long totalEncryptionTime = 0;
    private volatile long totalDecryptionTime = 0;
    private volatile long totalSignatureTime = 0;
    private volatile long totalVerificationTime = 0;
    
    // 数据量统计
    private volatile long totalDataEncrypted = 0;
    private volatile long totalDataDecrypted = 0;
    private volatile long totalDataSigned = 0;
    private volatile long totalDataVerified = 0;
    
    /**
     * 记录加密操作
     * 
     * @param algorithm 算法名称
     * @param dataSize 数据大小
     * @param duration 耗时（毫秒）
     * @param success 是否成功
     */
    public void recordEncryption(String algorithm, long dataSize, long duration, boolean success) {
        totalEncryptions.incrementAndGet();
        if (success) {
            successfulEncryptions.incrementAndGet();
        } else {
            failedEncryptions.incrementAndGet();
        }
        
        totalEncryptionTime += duration;
        totalDataEncrypted += dataSize;
        
        getAlgorithmMetrics(algorithm).recordEncryption(dataSize, duration, success);
    }
    
    /**
     * 记录解密操作
     * 
     * @param algorithm 算法名称
     * @param dataSize 数据大小
     * @param duration 耗时（毫秒）
     * @param success 是否成功
     */
    public void recordDecryption(String algorithm, long dataSize, long duration, boolean success) {
        totalDecryptions.incrementAndGet();
        if (success) {
            successfulDecryptions.incrementAndGet();
        } else {
            failedDecryptions.incrementAndGet();
        }
        
        totalDecryptionTime += duration;
        totalDataDecrypted += dataSize;
        
        getAlgorithmMetrics(algorithm).recordDecryption(dataSize, duration, success);
    }
    
    /**
     * 记录签名操作
     * 
     * @param algorithm 算法名称
     * @param dataSize 数据大小
     * @param duration 耗时（毫秒）
     * @param success 是否成功
     */
    public void recordSignature(String algorithm, long dataSize, long duration, boolean success) {
        totalSignatures.incrementAndGet();
        if (success) {
            successfulSignatures.incrementAndGet();
        } else {
            failedSignatures.incrementAndGet();
        }
        
        totalSignatureTime += duration;
        totalDataSigned += dataSize;
        
        getAlgorithmMetrics(algorithm).recordSignature(dataSize, duration, success);
    }
    
    /**
     * 记录验证操作
     * 
     * @param algorithm 算法名称
     * @param dataSize 数据大小
     * @param duration 耗时（毫秒）
     * @param success 是否成功
     */
    public void recordVerification(String algorithm, long dataSize, long duration, boolean success) {
        totalVerifications.incrementAndGet();
        if (success) {
            successfulVerifications.incrementAndGet();
        } else {
            failedVerifications.incrementAndGet();
        }
        
        totalVerificationTime += duration;
        totalDataVerified += dataSize;
        
        getAlgorithmMetrics(algorithm).recordVerification(dataSize, duration, success);
    }
    
    /**
     * 获取总加密操作数
     * 
     * @return 总加密操作数
     */
    public long getTotalEncryptions() {
        return totalEncryptions.get();
    }
    
    /**
     * 获取成功加密操作数
     * 
     * @return 成功加密操作数
     */
    public long getSuccessfulEncryptions() {
        return successfulEncryptions.get();
    }
    
    /**
     * 获取失败加密操作数
     * 
     * @return 失败加密操作数
     */
    public long getFailedEncryptions() {
        return failedEncryptions.get();
    }
    
    /**
     * 获取总解密操作数
     * 
     * @return 总解密操作数
     */
    public long getTotalDecryptions() {
        return totalDecryptions.get();
    }
    
    /**
     * 获取成功解密操作数
     * 
     * @return 成功解密操作数
     */
    public long getSuccessfulDecryptions() {
        return successfulDecryptions.get();
    }
    
    /**
     * 获取失败解密操作数
     * 
     * @return 失败解密操作数
     */
    public long getFailedDecryptions() {
        return failedDecryptions.get();
    }
    
    /**
     * 获取总签名操作数
     * 
     * @return 总签名操作数
     */
    public long getTotalSignatures() {
        return totalSignatures.get();
    }
    
    /**
     * 获取成功签名操作数
     * 
     * @return 成功签名操作数
     */
    public long getSuccessfulSignatures() {
        return successfulSignatures.get();
    }
    
    /**
     * 获取失败签名操作数
     * 
     * @return 失败签名操作数
     */
    public long getFailedSignatures() {
        return failedSignatures.get();
    }
    
    /**
     * 获取总验证操作数
     * 
     * @return 总验证操作数
     */
    public long getTotalVerifications() {
        return totalVerifications.get();
    }
    
    /**
     * 获取成功验证操作数
     * 
     * @return 成功验证操作数
     */
    public long getSuccessfulVerifications() {
        return successfulVerifications.get();
    }
    
    /**
     * 获取失败验证操作数
     * 
     * @return 失败验证操作数
     */
    public long getFailedVerifications() {
        return failedVerifications.get();
    }
    
    /**
     * 获取加密成功率
     * 
     * @return 加密成功率（0.0-1.0）
     */
    public double getEncryptionSuccessRate() {
        long total = totalEncryptions.get();
        return total > 0 ? (double) successfulEncryptions.get() / total : 0.0;
    }
    
    /**
     * 获取解密成功率
     * 
     * @return 解密成功率（0.0-1.0）
     */
    public double getDecryptionSuccessRate() {
        long total = totalDecryptions.get();
        return total > 0 ? (double) successfulDecryptions.get() / total : 0.0;
    }
    
    /**
     * 获取签名成功率
     * 
     * @return 签名成功率（0.0-1.0）
     */
    public double getSignatureSuccessRate() {
        long total = totalSignatures.get();
        return total > 0 ? (double) successfulSignatures.get() / total : 0.0;
    }
    
    /**
     * 获取验证成功率
     * 
     * @return 验证成功率（0.0-1.0）
     */
    public double getVerificationSuccessRate() {
        long total = totalVerifications.get();
        return total > 0 ? (double) successfulVerifications.get() / total : 0.0;
    }
    
    /**
     * 获取平均加密时间
     * 
     * @return 平均加密时间（毫秒）
     */
    public double getAverageEncryptionTime() {
        long total = totalEncryptions.get();
        return total > 0 ? (double) totalEncryptionTime / total : 0.0;
    }
    
    /**
     * 获取平均解密时间
     * 
     * @return 平均解密时间（毫秒）
     */
    public double getAverageDecryptionTime() {
        long total = totalDecryptions.get();
        return total > 0 ? (double) totalDecryptionTime / total : 0.0;
    }
    
    /**
     * 获取平均签名时间
     * 
     * @return 平均签名时间（毫秒）
     */
    public double getAverageSignatureTime() {
        long total = totalSignatures.get();
        return total > 0 ? (double) totalSignatureTime / total : 0.0;
    }
    
    /**
     * 获取平均验证时间
     * 
     * @return 平均验证时间（毫秒）
     */
    public double getAverageVerificationTime() {
        long total = totalVerifications.get();
        return total > 0 ? (double) totalVerificationTime / total : 0.0;
    }
    
    /**
     * 获取总加密数据量
     * 
     * @return 总加密数据量（字节）
     */
    public long getTotalDataEncrypted() {
        return totalDataEncrypted;
    }
    
    /**
     * 获取总解密数据量
     * 
     * @return 总解密数据量（字节）
     */
    public long getTotalDataDecrypted() {
        return totalDataDecrypted;
    }
    
    /**
     * 获取总签名数据量
     * 
     * @return 总签名数据量（字节）
     */
    public long getTotalDataSigned() {
        return totalDataSigned;
    }
    
    /**
     * 获取总验证数据量
     * 
     * @return 总验证数据量（字节）
     */
    public long getTotalDataVerified() {
        return totalDataVerified;
    }
    
    /**
     * 获取算法指标
     * 
     * @param algorithm 算法名称
     * @return 算法指标
     */
    public AlgorithmMetrics getAlgorithmMetrics(String algorithm) {
        return algorithmMetrics.computeIfAbsent(algorithm, k -> new AlgorithmMetrics(algorithm));
    }
    
    /**
     * 获取所有算法指标
     * 
     * @return 算法指标映射
     */
    public Map<String, AlgorithmMetrics> getAllAlgorithmMetrics() {
        return new ConcurrentHashMap<>(algorithmMetrics);
    }
    
    /**
     * 重置所有指标
     */
    public void reset() {
        totalEncryptions.set(0);
        successfulEncryptions.set(0);
        failedEncryptions.set(0);
        
        totalDecryptions.set(0);
        successfulDecryptions.set(0);
        failedDecryptions.set(0);
        
        totalSignatures.set(0);
        successfulSignatures.set(0);
        failedSignatures.set(0);
        
        totalVerifications.set(0);
        successfulVerifications.set(0);
        failedVerifications.set(0);
        
        totalEncryptionTime = 0;
        totalDecryptionTime = 0;
        totalSignatureTime = 0;
        totalVerificationTime = 0;
        
        totalDataEncrypted = 0;
        totalDataDecrypted = 0;
        totalDataSigned = 0;
        totalDataVerified = 0;
        
        algorithmMetrics.clear();
    }
    
    @Override
    public String toString() {
        return String.format(
            "EncryptionMetrics:\n" +
            "  Encryptions: %d (Success: %d, Failed: %d, Rate: %.2f%%)\n" +
            "  Decryptions: %d (Success: %d, Failed: %d, Rate: %.2f%%)\n" +
            "  Signatures: %d (Success: %d, Failed: %d, Rate: %.2f%%)\n" +
            "  Verifications: %d (Success: %d, Failed: %d, Rate: %.2f%%)\n" +
            "  Avg Times: Enc=%.2fms, Dec=%.2fms, Sig=%.2fms, Ver=%.2fms\n" +
            "  Data Volumes: Enc=%dB, Dec=%dB, Sig=%dB, Ver=%dB",
            getTotalEncryptions(), getSuccessfulEncryptions(), getFailedEncryptions(), 
            getEncryptionSuccessRate() * 100,
            getTotalDecryptions(), getSuccessfulDecryptions(), getFailedDecryptions(), 
            getDecryptionSuccessRate() * 100,
            getTotalSignatures(), getSuccessfulSignatures(), getFailedSignatures(), 
            getSignatureSuccessRate() * 100,
            getTotalVerifications(), getSuccessfulVerifications(), getFailedVerifications(), 
            getVerificationSuccessRate() * 100,
            getAverageEncryptionTime(), getAverageDecryptionTime(), 
            getAverageSignatureTime(), getAverageVerificationTime(),
            getTotalDataEncrypted(), getTotalDataDecrypted(), 
            getTotalDataSigned(), getTotalDataVerified()
        );
    }
    
    /**
     * 算法指标类
     */
    public static class AlgorithmMetrics {
        
        private final String algorithm;
        
        // 操作统计
        private final AtomicLong encryptions = new AtomicLong(0);
        private final AtomicLong decryptions = new AtomicLong(0);
        private final AtomicLong signatures = new AtomicLong(0);
        private final AtomicLong verifications = new AtomicLong(0);
        
        // 成功统计
        private final AtomicLong successfulOps = new AtomicLong(0);
        private final AtomicLong failedOps = new AtomicLong(0);
        
        // 时间统计
        private volatile long totalTime = 0;
        
        // 数据量统计
        private volatile long totalData = 0;
        
        /**
         * 构造函数
         * 
         * @param algorithm 算法名称
         */
        public AlgorithmMetrics(String algorithm) {
            this.algorithm = algorithm;
        }
        
        /**
         * 记录加密操作
         */
        public void recordEncryption(long dataSize, long duration, boolean success) {
            encryptions.incrementAndGet();
            if (success) {
                successfulOps.incrementAndGet();
            } else {
                failedOps.incrementAndGet();
            }
            totalTime += duration;
            totalData += dataSize;
        }
        
        /**
         * 记录解密操作
         */
        public void recordDecryption(long dataSize, long duration, boolean success) {
            decryptions.incrementAndGet();
            if (success) {
                successfulOps.incrementAndGet();
            } else {
                failedOps.incrementAndGet();
            }
            totalTime += duration;
            totalData += dataSize;
        }
        
        /**
         * 记录签名操作
         */
        public void recordSignature(long dataSize, long duration, boolean success) {
            signatures.incrementAndGet();
            if (success) {
                successfulOps.incrementAndGet();
            } else {
                failedOps.incrementAndGet();
            }
            totalTime += duration;
            totalData += dataSize;
        }
        
        /**
         * 记录验证操作
         */
        public void recordVerification(long dataSize, long duration, boolean success) {
            verifications.incrementAndGet();
            if (success) {
                successfulOps.incrementAndGet();
            } else {
                failedOps.incrementAndGet();
            }
            totalTime += duration;
            totalData += dataSize;
        }
        
        /**
         * 获取算法名称
         * 
         * @return 算法名称
         */
        public String getAlgorithm() {
            return algorithm;
        }
        
        /**
         * 获取总操作数
         * 
         * @return 总操作数
         */
        public long getTotalOperations() {
            return encryptions.get() + decryptions.get() + signatures.get() + verifications.get();
        }
        
        /**
         * 获取成功操作数
         * 
         * @return 成功操作数
         */
        public long getSuccessfulOperations() {
            return successfulOps.get();
        }
        
        /**
         * 获取失败操作数
         * 
         * @return 失败操作数
         */
        public long getFailedOperations() {
            return failedOps.get();
        }
        
        /**
         * 获取成功率
         * 
         * @return 成功率（0.0-1.0）
         */
        public double getSuccessRate() {
            long total = getTotalOperations();
            return total > 0 ? (double) successfulOps.get() / total : 0.0;
        }
        
        /**
         * 获取平均时间
         * 
         * @return 平均时间（毫秒）
         */
        public double getAverageTime() {
            long total = getTotalOperations();
            return total > 0 ? (double) totalTime / total : 0.0;
        }
        
        /**
         * 获取总数据量
         * 
         * @return 总数据量（字节）
         */
        public long getTotalData() {
            return totalData;
        }
        
        @Override
        public String toString() {
            return String.format(
                "AlgorithmMetrics[%s]:\n" +
                "  Operations: %d (Success: %d, Failed: %d, Rate: %.2f%%)\n" +
                "  Avg Time: %.2fms\n" +
                "  Total Data: %dB",
                algorithm, getTotalOperations(), getSuccessfulOperations(), 
                getFailedOperations(), getSuccessRate() * 100,
                getAverageTime(), getTotalData()
            );
        }
    }
}
